package com.kimwu.kill.mall.order.web.controller;


import com.kimwu.kill.mall.item.common.dto.StockGetItemDTO;
import com.kimwu.kill.mall.order.common.dto.BuildOrderDTO;
import com.kimwu.kill.mall.order.web.entity.OrderInfo;
import com.kimwu.kill.mall.order.web.service.IOrderInfoService;
import com.kimwu.kill.mall.order.web.service.feign.ItemFeignService;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Random;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author KimWu
 * @since 2021-08-26
 */
@RestController
@RequestMapping("/orderInfo")
@Slf4j
public class OrderInfoController {

    @Resource
    private IOrderInfoService orderInfoService;
    @Resource
    private ItemFeignService itemFeignService;

    @Resource
    private RedisTemplate redisTemplate;

    private static final String TEMP_GOOD = "kill:mall:temp:order";

    /**
     * 秒杀下单接口
     * @param dto
     * @param request
     * @return
     */
    @PostMapping("/v1/buildOrder")
    @GlobalTransactional(rollbackFor = Exception.class)
    public String buildOrder(@RequestBody BuildOrderDTO dto, HttpServletRequest request) {
        //在实际情况中使用该方法，需要在修改库存时，同时delete 掉redis的数据
        Object o = redisTemplate.opsForValue().get(TEMP_GOOD + ":" + dto.getItemId());
        if (o == null) {
            int amount = new Random().nextInt(2) + 1;
            String s = itemFeignService.stockGetItemPre(new StockGetItemDTO(dto.getItemId(), amount));
            if ("失败".equals(s)) {
                redisTemplate.opsForValue().set(TEMP_GOOD + ":" + dto.getItemId(), "秒杀判断，库存已不足", 60, TimeUnit.SECONDS);
                log.info("【库存不足】下单数量 ： {}", amount);
                return "商品库存不足";
            }
            OrderInfo orderInfo = new OrderInfo(
                    null, null, request.getSession().getId(), dto.getItemId(),
                    Double.valueOf(s), amount, Double.valueOf(s) * amount
            );
            orderInfoService.saveAsync(orderInfo);
            log.info("【下单成功】下单数量 ： {}", amount);
            return "成功";
        } else {
            log.info("【库存不足】在预处理阶段进行拦截");
            return "商品库存不足";
        }
    }

}
